package com.tnsw.coreutils.queuemanager;

import java.util.ArrayList;
import android.util.Log;
import static com.tnsw.coreutils.StaticConfig.DEBUGMODE;

public class QDelegateManager implements iQM {
	
	private String logName = "QDelegateManager";
	
	private String queueName;
	private int noOfThread;
	
	private QM qMain;
	private iQM iqm;
		
	private ArrayList<QM> arrQM = new ArrayList<QM>();
	private int currentQMIdx = 0;
	
	public QDelegateManager(String queueName, int noOfThread, iQM iqm) {
		Log.i(this.logName, "qDelegateManager=" + queueName + " is being created.");
		this.iqm = iqm;
		
		this.queueName = queueName;
		this.noOfThread = noOfThread;
		
		this.qMain = new QM("Main-" + queueName, 5);
		this.qMain.addQMListener(this);
		
		this.createSubQueue();
	}
	
	public String getQueueName() {
		return(this.queueName);
	}
	
	private void createSubQueue() {
		int i;
		
		for (i = 0; i < this.noOfThread; i++) {
			QM qm = new QM(this.queueName + "-" + String.valueOf(i), 5);
			qm.addQMListener(this.iqm);
			// qm.start();
			
			this.arrQM.add(qm);
		}
		
	}
	
	public void addQDelegateListener(iQM iqm) {
		this.iqm = iqm;
	}
	
	public void start() {
		this.qMain.start();
		
		int i;
		for (i = 0; i < this.noOfThread; i++) {
			this.arrQM.get(i).start();
		}		
	}
	
	public void stop() {
		this.qMain.stop();
		
		int i;
		for (i = 0; i < this.noOfThread; i++) {
			this.arrQM.get(i).stop();
		}
	}
	
	public void resume() {
		this.qMain.resume();
		int i;
		for (i = 0; i < this.noOfThread; i++) {
			this.arrQM.get(i).resume();
		}
	}
	
	public void pause() {
		this.qMain.pause();
		int i;
		for (i = 0; i < this.noOfThread; i++) {
			this.arrQM.get(i).pause();
		}
	}
	
	public void onNewQueueReceived(QM sender, QueueInfo qi) {
		// qMain receives new message and need to distribute to subQueue
		if (qi.getForcedSubQueueId() == -1) {
			int idx = this.getNextQueueIdx();
			
			if (DEBUGMODE) Log.d(this.logName, "Distributing to Subqueue Idx=" + String.valueOf(idx));
			QM qm = this.arrQM.get(idx);
			qm.addNewQueue(qi);			
		} else {
			if (DEBUGMODE) Log.d(this.logName, "Distributing to forcedSubQueue Idx=" + String.valueOf(qi.getForcedSubQueueId()));
			QM qm = this.arrQM.get(qi.getForcedSubQueueId());
			qm.addNewQueue(qi);
		}
		

	}
	
	private synchronized int getNextQueueIdx() {
		
		if (this.currentQMIdx >= this.noOfThread-1) {
			this.currentQMIdx = 0;
		} else {
			this.currentQMIdx += 1;
		}
		
		return(this.currentQMIdx);
	}
	
	public void addNewQueue(QueueInfo qi) {
		if (DEBUGMODE) Log.i(this.logName, "New QueueInfo is added. (id=" + qi.getQueueId() + ")");
		this.qMain.addNewQueue(qi);
		
	}
}
